﻿/*
* 创建者：LIYINFAI
* 创建时间：2023/10/24 9:35:26
* 描述：
* --------------------------------------
* 修改说明：
* --------------------------------------
*/
using CommonLibrary;
using CommonLibrary.Forms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;

namespace BusinessLibrary
{
    /// <summary>
    /// 设备结果信息体
    /// </summary>
    public class MESDeviceResultEntity
    {
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 类型  单进整出：DZ   整进整出：ZZ   单进单出： DD,未传时默认按照ZZ 进行数据解析
        /// </summary>
        [JsonProperty("type")]
        public string TransformType { get; set; } = "DD";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("payload")]
        public string Payload { get; set; } = "";
    }
    /// <summary>
    /// 设备结果Payload
    /// </summary>
    public class MESResultPayloadEntity
    {
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 产线代码
        /// </summary>
        [JsonProperty("lineCode")]
        public string LineCode { get; set; } = "";
        /// <summary>
        /// 操作用户编码
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
        /// <summary>
        /// 物料编码
        /// </summary>
        [JsonProperty("materialCode")]
        public string MaterialCode { get; set; } = "";
        /// <summary>
        /// 采集时间
        /// </summary>
        [JsonProperty("recordDate")]
        public string RecordDate { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        /// <summary>
        /// 数量
        /// </summary>
        [JsonProperty("qty")]
        public int Qty { get; set; } = 1;
        /// <summary>
        /// 模组信息集合
        /// </summary>
        [JsonProperty("identification")]
        public MESResultIdentityEntity Identification { get; set; } = new MESResultIdentityEntity();
    }

    /// <summary>
    /// 出站数据信息体
    /// </summary>
    public class MESResultIdentityEntity
    {
        /// <summary>
        /// 模组标识码
        /// </summary>
        [JsonProperty("identification")]
        public string Identification { get; set; } = "";
        /// <summary>
        /// 质量状态
        /// </summary>
        [JsonProperty("qualityStatus")]
        public string QualityStatus { get; set; } = "";

        /// <summary>
        /// 采集项数组
        /// </summary>
        [JsonProperty("tagDataVOList")]
        public List<MESResultCollectItemEntity> TagDataVOList { get; set; } = new List<MESResultCollectItemEntity>();

    }
    /// <summary>
    /// 出站数据采集信息体
    /// </summary>
    public class MESResultCollectItemEntity
    {
        /// <summary>
        /// 设备采集代码
        /// </summary>
        [JsonProperty("tagCode")]
        public string TagCode { get; set; } = "";
        /// <summary>
        /// 采集值
        /// </summary>
        [JsonProperty("tagValue")]
        public string TagValue { get; set; } = "";
        /// <summary>
        /// 采集项采集时间
        /// </summary>
        [JsonProperty("tagTime")]
        public string TagTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        /// <summary>
        /// 采集项判断结果 Y/N
        /// </summary>
        [JsonProperty("tagCalculateResult")]
        public string TagCalculateResult { get; set; } = "";
        /// <summary>
        /// 备注
        /// </summary>
        [JsonProperty("tagRemark")]
        public string TagRemark { get; set; } = "";
    }
    /// <summary>
    /// 出站信息体
    /// </summary>
    public class MESOutStationEntity
    {
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 产线代码
        /// </summary>
        [JsonProperty("lineCode")]
        public string LineCode { get; set; } = "";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 操作用户编码
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
        /// <summary>
        /// 物料编码
        /// </summary>
        [JsonProperty("materialCode")]
        public string MaterialCode { get; set; } = "";
        /// <summary>
        /// 模组信息集合
        /// </summary>
        [JsonProperty("identiftyList")]
        public List<MESOutIdentityEntity> IdentiftyList { get; set; } = new List<MESOutIdentityEntity>();
    }

    /// <summary>
    /// 出站数据信息体
    /// </summary>
    public class MESOutIdentityEntity
    {
        /// <summary>
        /// 模组标识码
        /// </summary>
        [JsonProperty("identification")]
        public string Identification { get; set; } = "";
        /// <summary>
        /// 工单编码
        /// </summary>
        [JsonProperty("workOrderNum")]
        public string WorkOrderNum { get; set; } = "";
        /// <summary>
        /// 质量状态
        /// </summary>
        [JsonProperty("qualityStatus")]
        public string QualityStatus { get; set; } = "";
        /// <summary>
        /// ng信息
        /// </summary>
        [JsonProperty("ngMessage")]
        public string NGMessage { get; set; } = "";
        /// <summary>
        /// ng代码
        /// </summary>
        [JsonProperty("ngCode")]
        public List<string> NGCode { get; set; } = new List<string>();
        /// <summary>
        /// 采集时间
        /// </summary>
        [JsonProperty("recordDate")]
        public string RecordDate { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        /// <summary>
        /// 采集项数组
        /// </summary>
        [JsonProperty("tagDataVOList")]
        public List<MESOutCollectItemEntity> TagDataVOList { get; set; } = new List<MESOutCollectItemEntity>();

    }
    /// <summary>
    /// 出站数据采集信息体
    /// </summary>
    public class MESOutCollectItemEntity
    {
        /// <summary>
        /// 设备采集代码
        /// </summary>
        [JsonProperty("tagCode")]
        public string TagCode { get; set; } = "";
        /// <summary>
        /// 采集值
        /// </summary>
        [JsonProperty("tagValue")]
        public string TagValue { get; set; } = "";
        /// <summary>
        /// 采集项采集时间
        /// </summary>
        [JsonProperty("tagTime")]
        public string TagTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        /// <summary>
        /// 采集项判断结果 Y/N
        /// </summary>
        [JsonProperty("tagCalculateResult")]
        public string TagCalculateResult { get; set; } = "";
    }
    /// <summary>
    /// 进站信息体
    /// </summary>
    public class MESInStationEntity
    {
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 产线代码
        /// </summary>
        [JsonProperty("lineCode")]
        public string LineCode { get; set; } = "";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 产出条码
        /// </summary>
        [JsonProperty("identification")]
        public string Identification { get; set; } = "";
        /// <summary>
        /// 操作用户编码
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
    }
    /// <summary>
    /// 卡登录信息体
    /// </summary>
    public class MESCardLoginEntity
    {
        /// <summary>
        /// 登录类型
        /// </summary>
        [JsonProperty("loginType")]
        public string LoginType { get; set; } = "card";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 卡号
        /// </summary>
        [JsonProperty("userNo")]
        public string UserNo { get; set; } = "";
    }
    /// <summary>
    /// 密码登录信息体
    /// </summary>
    public class MESUserLoginEntity
    {
        /// <summary>
        /// 登录类型
        /// </summary>
        [JsonProperty("loginType")]
        public string LoginType { get; set; } = "card";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 用户名
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
        /// <summary>
        /// 密码
        /// </summary>
        [JsonProperty("passWord")]
        public string PassWord { get; set; } = "";
    }
    /// <summary>
    /// 设备状态单个信息体
    /// </summary>
    public class MESSingleStatusEntity
    {
        /// <summary>
        /// 故障代码
        /// </summary>
        [JsonProperty("faultCode")]
        public string FaultCode { get; set; } = "";
    }
    /// <summary>
    /// 设备状态信息体
    /// </summary>
    public class MESStatusEntity
    {
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 产线代码
        /// </summary>
        [JsonProperty("lineCode")]
        public string LineCode { get; set; } = "";
        /// <summary>
        /// 用户名
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        /// <summary>
        /// 采集时间
        /// </summary>
        [JsonProperty("recordDate")]
        public string RecordDate { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        /// <summary>
        /// 状态
        /// </summary>
        [JsonProperty("statusCode")]
        public string StatusCode { get; set; } = "";
        ///// <summary>
        ///// 物料编码
        ///// </summary>
        //[JsonProperty("materialCode")]
        //public string MaterialCode { get; set; } = "";
        /// <summary>
        /// 上传时间
        /// </summary>
        [JsonProperty("uploadTime")]
        public string UploadTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        /// <summary>
        /// guid
        /// </summary>
        [JsonProperty("guid")]
        public string GuidID { get; set; } = Guid.NewGuid().ToString("D");

        /// <summary>
        /// 故障集合
        /// </summary>
        [JsonProperty("faultCodeList")]
        public List<MESSingleStatusEntity> FaultCodeList { get; set; } = new List<MESSingleStatusEntity>();
    }
    /// <summary>
    /// 报警信息体
    /// </summary>
    public class MESSingleAlarmEntity
    {
        /// <summary>
        /// 报警开始时间
        /// </summary>
        [JsonProperty("alarmStartTime")]
        public string AlarmStartTime { get; set; } = "";
        /// <summary>
        /// 报警结束时间
        /// </summary>
        [JsonProperty("alarmEndTime")]
        public string AlarmEndTime { get; set; } = "";
        /// <summary>
        /// 报警类型
        /// </summary>
        [JsonProperty("alarmType")]
        public string AlarmType { get; set; } = "A";
        /// <summary>
        /// 报警名称
        /// </summary>
        [JsonProperty("alarmName")]
        public string AlarmName { get; set; } = "";
        /// <summary>
        /// 设备故障代码
        /// </summary>
        [JsonProperty("faultCode")]
        public string FaultCode { get; set; } = "";
    }
    /// <summary>
    /// 报警数据信息体
    /// </summary>
    public class MESAlarmEntity
    {
        /// <summary>
        /// 工厂代码
        /// </summary>
        [JsonProperty("siteCode")]
        public string SiteCode { get; set; } = "";
        /// <summary>
        /// 产线代码
        /// </summary>
        [JsonProperty("lineCode")]
        public string LineCode { get; set; } = "";
        /// <summary>
        /// 用户名
        /// </summary>
        [JsonProperty("userName")]
        public string UserName { get; set; } = "";
        /// <summary>
        /// 设备编号
        /// </summary>
        [JsonProperty("equipNum")]
        public string EquipNum { get; set; } = "";
        ///// <summary>
        ///// 物料编码
        ///// </summary>
        //[JsonProperty("materialCode")]
        //public string MaterialCode { get; set; } = "";
        /// <summary>
        /// 采集时间
        /// </summary>
        [JsonProperty("recordDate")]
        public string RecordDate { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        /// <summary>
        /// guid
        /// </summary>
        [JsonProperty("guid")]
        public string GuidID { get; set; } = Guid.NewGuid().ToString("D");

        /// <summary>
        /// 故障集合
        /// </summary>
        [JsonProperty("alarmLineList")]
        public List<MESSingleAlarmEntity> AlarmLineList { get; set; } = new List<MESSingleAlarmEntity>();
    }
    /// <summary>
    /// MESHelper
    /// </summary>
    public class MES : IPlugin
    {
        /// <summary>
        /// 描述信息
        /// </summary>
        public string Description => "MES通讯";
        /// <summary>
        /// 执行方法
        /// </summary>
        /// <param name="pluginParam">参数</param>
        /// <returns></returns>
        public string Excute(PluginParamEntity pluginParam)
        {
            string result = string.Empty;
            if (pluginParam != null)
            {
                string identity = pluginParam.Identity.ToUpper();
                switch (identity)
                {
                    case "MES_ISONLINE": result = IsOnline(pluginParam); break;
                    case "MES_START_ALARM": result = StartAlarm(pluginParam); break;
                    case "MES_DEVICE_STATUS": result = DeviceStatus(pluginParam); break;
                }
            }
            return result;
        }
        /// <summary>
        /// 返回一个窗口
        /// </summary>
        /// <param name="pluginParam"></param>
        /// <returns></returns>

        public HWFrmWithTitle GetForm(PluginParamEntity pluginParam)
        {
            HWFrmWithTitle result = null;
            if (pluginParam != null)
            {
                string identity = pluginParam.Identity.ToUpper();
                switch (identity)
                {
                    case "MES_FORM": result = new FormMESOptions(); break;
                    case "MES_FORM_LOGIN": result = new FormMESLogin(); break;
                }
            }
            return result;
        }
        /// <summary>
        /// 返回一个 Bitmap
        /// </summary>
        /// <returns></returns>
        public Bitmap GetBitmap()
        {
            return null;
        }
        /// <summary>
        /// MES_ISONLINE
        /// 是否在线
        /// </summary>
        /// <returns></returns>
        private string IsOnline(PluginParamEntity pluginParam)
        {
            string methodName = "是否在线";
            this.Info($"【{pluginParam.Tag}】开始 - {methodName}");

            string result = "False";
            try
            {
                if (!string.IsNullOrWhiteSpace(MesBusiness.Instance().Url))
                {
                    var uri = new Uri(MesBusiness.Instance().Url);
                    result = CommonHelper.DoPing(uri.Host).ToString();
                }
            }
            catch (Exception ex)
            {
                this.Error(ex);
            }
            this.Info($"【{pluginParam.Tag}】结束 - {methodName}，返回结果：{result}");
            return result;
        }
        /// <summary>
        /// MES_START_ALARM
        /// MES报警开始
        /// </summary>
        /// <returns></returns>
        private string StartAlarm(PluginParamEntity pluginParam)
        {
            string methodName = "MES报警开始";
            this.Info($"【{pluginParam.Tag}】开始 - {methodName}");

            string result = "False";
            try
            {
                if (!MesCommonHelper.IsMESOffline)
                {
                    var entity = CommonHelper.GetJson(pluginParam.ParamString, new MESAlarmExcuteEntity()
                    {
                        StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    });
                    var mesResult = MesBusiness.AlarmCheck(entity.AlarmCode, entity.AlarmContent, entity.StartTime, entity.EndTime);
                    result = mesResult.IsSuccessReturn ? "True" : result;
                }
            }
            catch (Exception ex)
            {
                this.Error(ex);
            }
            this.Info($"【{pluginParam.Tag}】结束 - {methodName}，返回结果：{result}");
            return result;
        }
        /// <summary>
        /// MES_DEVICE_STATUS
        /// MES设备状态
        /// 有4种设备状态信息。Run：（正常运行）、Alert：（故障调试）、Idle：（闲置待机）、Maintain（停止运行）
        /// </summary>
        /// <returns></returns>
        private string DeviceStatus(PluginParamEntity pluginParam)
        {
            string methodName = "MES设备状态";
            this.Info($"【{pluginParam.Tag}】开始 - {methodName}");

            string result = "False";
            try
            {
                if (!MesCommonHelper.IsMESOffline)
                {
                    var entity = CommonHelper.GetJson(pluginParam.ParamString, new MESStatusExcuteEntity()
                    {
                        Status = EPLCState.Idle
                    });
                    var status = "Idle";
                    switch (entity.Status)
                    {
                        case EPLCState.Alarm: status = "Alert"; break;
                        case EPLCState.AutoRunning: status = "Run"; break;
                        case EPLCState.Maintain: status = "Idle"; break;
                        case EPLCState.Stoping: status = "Maintain"; break;
                    }
                    var mesResult = MesBusiness.StatusCheck(status);
                    result = mesResult.IsSuccessReturn ? "True" : result;
                }
            }
            catch (Exception ex)
            {
                this.Error(ex);
            }
            this.Info($"【{pluginParam.Tag}】结束 - {methodName}，返回结果：{result}");
            return result;
        }
    }

    /// <summary>
    /// MES帮助类
    /// </summary>
    public class MesBusiness
    {
        /// <summary>
        /// 未知错误
        /// </summary>
        public const string UNKNOWN_ERROR = "9999";
        /// <summary>
        /// 通讯超时
        /// </summary>
        public const string COMMUNICATION_TIMEOUT = "8888";
        /// <summary>
        /// 程序异常
        /// </summary>
        public const string PROGRAM_EXCEPTION = "7777";

        /// <summary>
        /// mes api 地址
        /// </summary>
        [Description("Url")]
        [JsonProperty(PropertyName = "Url")]
        public string Url { get; set; } = "http://10.34.1.103:8080/core";


        /// <summary>
        /// 物料编码
        /// </summary>
        [Description("MaterialCode")]
        [JsonProperty(PropertyName = "MaterialCode")]
        public string MaterialCode { get; set; } = "91000612";

        /// <summary>
        /// 工单编码
        /// </summary>
        [Description("WorkOrderNum")]
        [JsonProperty(PropertyName = "WorkOrderNum")]
        public string WorkOrderNum { get; set; } = "2022111403";
        /// <summary>
        /// 数据传输类型
        /// </summary>
        [Description("DataTransformType")]
        [JsonProperty(PropertyName = "DataTransformType")]
        public string DataTransformType { get; set; } = "DD";


        /// <summary>
        /// 登录接口
        /// </summary>
        [Description("LoginApi")]
        [JsonProperty(PropertyName = "LoginApi")]
        public string LoginApi { get; set; } = "/api/public/scada/equipment/base/user/login/verify";
        /// <summary>
        /// 登录接口超时时间（单位毫秒）
        /// </summary>
        [Description("LoginApiTimeout")]
        [JsonProperty(PropertyName = "LoginApiTimeout")]
        public int LoginApiTimeout { get; set; } = 2000;
        /// <summary>
        /// 登录接口失败重试次数（默认0）
        /// </summary>
        [Description("LoginApiRetryTimes")]
        [JsonProperty(PropertyName = "LoginApiRetryTimes")]
        public int LoginApiRetryTimes { get; set; } = 0;


        /// <summary>
        /// 通用进站
        /// </summary>
        [Description("InStationApi")]
        [JsonProperty(PropertyName = "InStationApi")]
        public string InStationApi { get; set; } = "/api/public/scada/cell/InStation";
        /// <summary>
        /// 通用进站接口超时时间（单位毫秒）
        /// </summary>
        [Description("InStationTimeout")]
        [JsonProperty(PropertyName = "InStationTimeout")]
        public int InStationTimeout { get; set; } = 2000;
        /// <summary>
        /// 通用进站接口失败重试次数（默认0）
        /// </summary>
        [Description("InStationRetryTimes")]
        [JsonProperty(PropertyName = "InStationRetryTimes")]
        public int InStationRetryTimes { get; set; } = 0;


        /// <summary>
        /// 通用出站
        /// </summary>
        [Description("OutStationApi")]
        [JsonProperty(PropertyName = "OutStationApi")]
        public string OutStationApi { get; set; } = "/api/public/scada/cell/outStation";
        /// <summary>
        /// 通用出站接口超时时间（单位毫秒）
        /// </summary>
        [Description("OutStationTimeout")]
        [JsonProperty(PropertyName = "OutStationTimeout")]
        public int OutStationTimeout { get; set; } = 2000;
        /// <summary>
        /// 通用出站接口失败重试次数（默认0）
        /// </summary>
        [Description("OutStationRetryTimes")]
        [JsonProperty(PropertyName = "OutStationRetryTimes")]
        public int OutStationRetryTimes { get; set; } = 0;


        /// <summary>
        /// 设备结果
        /// </summary>
        [Description("DeviceResultApi")]
        [JsonProperty(PropertyName = "DeviceResultApi")]
        public string DeviceResultApi { get; set; } = "/api/public/scada/product/process/param/result";
        /// <summary>
        /// 设备结果接口超时时间（单位毫秒）
        /// </summary>
        [Description("DeviceResultTimeout")]
        [JsonProperty(PropertyName = "DeviceResultTimeout")]
        public int DeviceResultTimeout { get; set; } = 2000;
        /// <summary>
        /// 设备结果接口失败重试次数（默认0）
        /// </summary>
        [Description("DeviceResultRetryTimes")]
        [JsonProperty(PropertyName = "DeviceResultRetryTimes")]
        public int DeviceResultRetryTimes { get; set; } = 0;


        /// <summary>
        /// 设备状态
        /// </summary>
        [Description("DeviceStatusApi")]
        [JsonProperty(PropertyName = "DeviceStatusApi")]
        public string DeviceStatusApi { get; set; } = "/api/public/scada/eve/pm/eqm/run/status/operation";
        /// <summary>
        /// 设备状态接口超时时间（单位毫秒）
        /// </summary>
        [Description("DeviceStatusTimeout")]
        [JsonProperty(PropertyName = "DeviceStatusTimeout")]
        public int DeviceStatusTimeout { get; set; } = 2000;
        /// <summary>
        /// 设备状态接口失败重试次数（默认0）
        /// </summary>
        [Description("DeviceStatusRetryTimes")]
        [JsonProperty(PropertyName = "DeviceStatusRetryTimes")]
        public int DeviceStatusRetryTimes { get; set; } = 0;


        /// <summary>
        /// 报警
        /// </summary>
        [Description("AlarmApi")]
        [JsonProperty(PropertyName = "AlarmApi")]
        public string AlarmApi { get; set; } = "/api/public/scada/equipment/alarm/currency";
        /// <summary>
        /// 报警接口超时时间（单位毫秒）
        /// </summary>
        [Description("AlarmTimeout")]
        [JsonProperty(PropertyName = "AlarmTimeout")]
        public int AlarmTimeout { get; set; } = 2000;
        /// <summary>
        /// 报警接口失败重试次数（默认0）
        /// </summary>
        [Description("AlarmRetryTimes")]
        [JsonProperty(PropertyName = "AlarmRetryTimes")]
        public int AlarmRetryTimes { get; set; } = 0;


        /// <summary>
        /// 配置文件
        /// </summary>
        static string CONFIG_FILE_PATH = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "MesConfig.json");
        private static MesBusiness instance = null;
        /// <summary>
        /// 锁
        /// </summary>
        private static object LOCK_OBJ = new object();
        /// <summary>
        /// 实例对象
        /// </summary>
        /// <returns></returns>
        public static MesBusiness Instance(bool reload = false)
        {
            if (reload || instance == null)
            {
                try
                {
                    instance = CommonHelper.GetJsonFromFile(CONFIG_FILE_PATH, new MesBusiness());
                }
                catch (Exception ex)
                {
                    instance = new MesBusiness();
                    LogHelper.Error(ex);
                }
            }
            return instance;
        }
        /// <summary>
        /// 保存
        /// </summary>
        public void Save()
        {
            lock (LOCK_OBJ)
            {
                CommonHelper.SaveToJsonFile(instance, CONFIG_FILE_PATH);
                CommonHelper.SaveToJsonFile(instance, CONFIG_FILE_PATH);
            }
        }
        private static void ShowMESInfoToUI(string interfaceName, MESResult mesResult)
        {
            if (mesResult != null && APPInstance.AppInstanceShowMESMessageInListView != null)
            {
                APPInstance.AppInstanceShowMESMessageInListView($"【{interfaceName}】返回结果：{CommonHelper.GetJsonString(mesResult, Formatting.None)}",
                    mesResult.IsSuccessReturn ? Color.White : Color.Red);
            }
        }
        /// <summary>
        /// 设备结果参数上传
        /// </summary>
        /// <returns></returns>
        public static MESResult DeviceResultCheck(ProductInfo productInfo)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (productInfo != null && !string.IsNullOrWhiteSpace(productInfo.BarCode)
                && !productInfo.BarCode.ToUpper().Equals("ERROR"))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(
                    new MESDeviceResultEntity()
                    {
                        EquipNum = basicSetting.EquipmentCode,
                        Payload = CommonHelper.GetJsonString(
                      new MESResultPayloadEntity()
                      {
                          SiteCode = basicSetting.SiteCode,
                          LineCode = basicSetting.LineCode,
                          UserName = MesCommonHelper.MES_USERNAME,
                          MaterialCode = mesBusiness.MaterialCode,
                          Identification = new MESResultIdentityEntity()
                          {
                              Identification = productInfo.BarCode,
                              QualityStatus = productInfo.Quality == "100" ? "OK" : "NG",
                              TagDataVOList = new List<MESResultCollectItemEntity> {
                                new MESResultCollectItemEntity()
                                {
                                    TagCode="HeliumTestResults",
                                    TagCalculateResult = productInfo.HeliumResult=="100"?"Y":"N",
                                    TagValue = productInfo.LeakRate
                                },
                                new MESResultCollectItemEntity()
                                {
                                    TagCode="LeakageCurrentTestResults",
                                    TagCalculateResult = productInfo.H3153Result=="100"?"Y":"N",
                                    TagValue = productInfo.Current
                                },
                                new MESResultCollectItemEntity()
                                {
                                    TagCode="InsulationTestResults",
                                    TagCalculateResult = productInfo.ST5520Result=="100"?"Y":"N",
                                    TagValue = productInfo.Resistance
                                }
                                }
                          }
                      }, Formatting.None)
                    }
                    );
                result = CallApi($"【MES结果参数上传】条码：{productInfo.BarCode}，操作用户：{MesCommonHelper.MES_USERNAME}",
                    $"{mesBusiness.Url}{mesBusiness.DeviceResultApi}",
                    body, mesBusiness.DeviceResultRetryTimes + 1,
                    mesBusiness.DeviceResultTimeout);
            }
            else
            {
                result.Message = "产品为空";
            }
            ShowMESInfoToUI("设备结果参数上传", result);
            return result;
        }
        /// <summary>
        /// 入站
        /// </summary>
        /// <returns></returns>
        public static MESResult InCheck(string barcode, string scanTime, short scanResult)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (!string.IsNullOrWhiteSpace(barcode))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESInStationEntity()
                {
                    SiteCode = basicSetting.SiteCode,
                    LineCode = basicSetting.LineCode,
                    EquipNum = basicSetting.EquipmentCode,
                    Identification = barcode,
                    UserName = MesCommonHelper.MES_USERNAME,
                });
                result = CallApi($"【MES入站上传】条码：{barcode}，操作用户：{MesCommonHelper.MES_USERNAME}",
                    $"{mesBusiness.Url}{mesBusiness.InStationApi}",
                    body, mesBusiness.InStationRetryTimes + 1,
                    mesBusiness.InStationTimeout);
            }
            else
            {
                result.Message = "条码为空";
            }
            ShowMESInfoToUI("入站", result);
            return result;
        }
        /// <summary>
        /// 出站
        /// </summary>
        /// <returns></returns>
        public static MESResult OutCheck(ProductInfo productInfo)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (productInfo != null && !string.IsNullOrWhiteSpace(productInfo.BarCode)
                && !productInfo.BarCode.ToUpper().Equals("ERROR"))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESOutStationEntity()
                {
                    SiteCode = basicSetting.SiteCode,
                    LineCode = basicSetting.LineCode,
                    EquipNum = basicSetting.EquipmentCode,
                    MaterialCode = mesBusiness.MaterialCode,
                    UserName = MesCommonHelper.MES_USERNAME,
                    IdentiftyList = new List<MESOutIdentityEntity>() {
                      new MESOutIdentityEntity()
                      {
                           Identification = productInfo.BarCode,
                           QualityStatus=productInfo.Quality=="100"?"OK":"NG",
                           WorkOrderNum =mesBusiness.WorkOrderNum,
                           TagDataVOList  = new List<MESOutCollectItemEntity> {
                                new MESOutCollectItemEntity()
                                {
                                    TagCode="HeliumTestResults",
                                    TagCalculateResult = productInfo.HeliumResult=="100"?"Y":"N",
                                    TagValue = productInfo.LeakRate
                                },
                                new MESOutCollectItemEntity()
                                {
                                    TagCode="LeakageCurrentTestResults",
                                    TagCalculateResult = productInfo.H3153Result=="100"?"Y":"N",
                                    TagValue = productInfo.Current
                                },
                                new MESOutCollectItemEntity()
                                {
                                    TagCode="InsulationTestResults",
                                    TagCalculateResult = productInfo.ST5520Result=="100"?"Y":"N",
                                    TagValue = productInfo.Resistance
                                }
                           }
                      }
                    }
                });
                result = CallApi($"【MES出站上传】条码：{productInfo.BarCode}，操作用户：{MesCommonHelper.MES_USERNAME}",
                    $"{mesBusiness.Url}{mesBusiness.OutStationApi}",
                    body, mesBusiness.OutStationRetryTimes + 1,
                    mesBusiness.OutStationTimeout);
            }
            else
            {
                result.Message = "产品为空";
            }
            ShowMESInfoToUI("出站", result);
            return result;
        }
        /// <summary>
        /// 密码登录
        /// </summary>
        /// <returns></returns>
        public static MESResult LoginPasswordCheck(string userName, string password)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(password))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESUserLoginEntity()
                {
                    EquipNum = basicSetting.EquipmentCode,
                    SiteCode = basicSetting.SiteCode,
                    UserName = userName,
                    PassWord = password,
                    LoginType = "password"
                });
                result = CallApi($"【MES密码登录】用户名：{userName}，密码：{password}",
                    $"{mesBusiness.Url}{mesBusiness.LoginApi}",
                    body, mesBusiness.LoginApiRetryTimes + 1,
                    mesBusiness.LoginApiTimeout);
            }
            else
            {
                result.Message = "用户名或密码为空";
            }
            ShowMESInfoToUI("登录接口-密码登录", result);
            return result;
        }
        /// <summary>
        /// 卡登录
        /// </summary>
        /// <returns></returns>
        public static MESResult LoginCardCheck(string cardNo)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (!string.IsNullOrWhiteSpace(cardNo))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESCardLoginEntity()
                {
                    EquipNum = basicSetting.EquipmentCode,
                    SiteCode = basicSetting.SiteCode,
                    UserNo = cardNo
                });
                result = CallApi($"【MES卡号登录】卡号：{cardNo}",
                    $"{mesBusiness.Url}{mesBusiness.LoginApi}",
                    body, mesBusiness.LoginApiRetryTimes + 1,
                    mesBusiness.LoginApiTimeout);
            }
            else
            {
                result.Message = "卡号为空";
            }
            ShowMESInfoToUI("登录接口-卡登录", result);
            return result;
        }
        /// <summary>
        /// 设备状态接口
        /// </summary>
        /// <returns></returns>
        public static MESResult StatusCheck(string status)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (!string.IsNullOrWhiteSpace(status))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESStatusEntity()
                {
                    EquipNum = basicSetting.EquipmentCode,
                    SiteCode = basicSetting.SiteCode,
                    UserName = MesCommonHelper.MES_USERNAME,
                    LineCode = basicSetting.LineCode,
                    //MaterialCode = mesBusiness.MaterialCode,
                    StatusCode = status
                });
                result = CallApi($"【MES设备状态上传】设备状态：{status}",
                    $"{mesBusiness.Url}{mesBusiness.DeviceStatusApi}",
                    body, mesBusiness.DeviceStatusRetryTimes + 1,
                    mesBusiness.DeviceStatusTimeout);
            }
            else
            {
                result.Message = "状态为空";
            }
            ShowMESInfoToUI("设备状态接口", result);
            return result;
        }
        /// <summary>
        /// 报警接口
        /// </summary>
        /// <returns></returns>
        public static MESResult AlarmCheck(string alarmCode, string alarmContent, string startTime, string endTime)
        {
            MESResult result = new MESResult();
            //模拟，后续根据实际情况更改
            if (!string.IsNullOrWhiteSpace(alarmCode) && !string.IsNullOrWhiteSpace(alarmContent))
            {
                var basicSetting = AppBasicSetting.Instance();
                var mesBusiness = Instance();

                string body = CommonHelper.GetJsonString(new MESAlarmEntity()
                {
                    EquipNum = basicSetting.EquipmentCode,
                    SiteCode = basicSetting.SiteCode,
                    UserName = MesCommonHelper.MES_USERNAME,
                    LineCode = basicSetting.LineCode,
                    //MaterialCode = mesBusiness.MaterialCode,
                    AlarmLineList = new List<MESSingleAlarmEntity>() {
                        new MESSingleAlarmEntity()
                        {
                            FaultCode = alarmCode,
                            AlarmName = alarmContent,
                            AlarmStartTime = string.IsNullOrWhiteSpace(startTime)? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"):startTime,
                            AlarmEndTime = string.IsNullOrWhiteSpace(endTime)?null:endTime,
                        }
                     }
                });
                result = CallApi($"【MES报警上传】报警代码：{alarmCode}，报警内容：{alarmContent}，开始时间：{startTime}，结束时间：{endTime}",
                    $"{mesBusiness.Url}{mesBusiness.AlarmApi}",
                    body, mesBusiness.AlarmRetryTimes + 1,
                    mesBusiness.AlarmTimeout);
            }
            else
            {
                result.Message = "报警代码或报警内容为空";
            }
            ShowMESInfoToUI("报警接口", result);
            return result;
        }
        private static MESResult CallApi(string tag, string url, string body, int maxTryTimes = 1, int timeout = 2000)
        {
            MESResult result = new MESResult();
            for (int i = 0; i < maxTryTimes; i++)
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                LogHelper.Mes($"{tag}，第{i + 1}次调用开始，{timeout}，{url}，{body}");
                try
                {
                    //调用接口
                    var postResult = ApiHelper.Post(url, body, "", "", "Application/json;charset=UTF-8", timeout);
                    if (!string.IsNullOrWhiteSpace(postResult.result))
                    {
                        result = CommonHelper.GetJson(postResult.result, new MESResult());
                    }
                    if (postResult.isTimeout)
                    {
                        result.Code = COMMUNICATION_TIMEOUT;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
                finally
                {
                    stopwatch.Stop();
                    LogHelper.Mes($"{tag}，第{i + 1}次调用结束，耗时 {stopwatch.ElapsedMilliseconds} 毫秒，{CommonHelper.GetJsonString(result, Formatting.None)}，{body}");
                }
                if (result.IsCorrectResponse)
                {
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 获取错误信息
        /// </summary>
        /// <param name="mesResult"></param>
        /// <returns></returns>
        public static string GetMessage(MESResult mesResult)
        {
            string result = string.Empty;
            if (mesResult != null && !string.IsNullOrWhiteSpace(mesResult.Message))
            {
                result = mesResult.Code.Equals(UNKNOWN_ERROR) ?
                    "未知错误" :
                    (mesResult.Code.Equals(COMMUNICATION_TIMEOUT) ? "通讯超时" :
                    (mesResult.Code.Equals(PROGRAM_EXCEPTION) ? $"程序异常：{mesResult.Message}"
                    : mesResult.Message));
            }
            return result;
        }
    }

    /// <summary>
    /// MES 返回结果
    /// </summary>
    public class MESResult
    {
        /// <summary>
        /// 响应代码
        /// 200 成功响应
        /// 9999 未知错误（自定义）
        /// 8888 超时（自定义）
        /// 7777 程序异常（自定义）
        /// </summary>
        [JsonProperty("code")]
        public string Code { get; set; } = MesBusiness.UNKNOWN_ERROR;
        /// <summary>
        /// 响应结果 false：失败，true：成功
        /// </summary>
        [JsonProperty("success")]
        public bool Success { get; set; } = false;
        /// <summary>
        /// 响应信息
        /// </summary>
        [JsonProperty("message")]
        public string Message { get; set; } = string.Empty;
        /// <summary>
        /// 消息分类
        /// </summary>
        [JsonProperty("category")]
        public string Category { get; set; } = string.Empty;
        /// <summary>
        /// 是否成功响应
        /// </summary>
        [JsonIgnore]
        public bool IsCorrectResponse => Code.Equals("200");
        /// <summary>
        /// 是否有正确返回
        /// </summary>
        [JsonIgnore]
        public bool IsSuccessReturn => Code.Equals("200") && Success;
    }
}
